<?php


namespace App\Services\Admin\V1;


use App\Models\V1\Menu;
use App\Models\V1\Role;
use App\Models\V1\Permission;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Collection;
use App\Http\Requests\Admin\V1\RoleStoreRequest;
use App\Http\Requests\Admin\V1\RoleUpdateRequest;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

class RoleService
{
    /**
     * @expalin GET ALL ROLES
     * @return Collection
     * @method
     * @author 陈文小超
     * @maxim from专注to执行
     * @time 2021/3/31/11:01
     */
    public function all(): Collection
    {
        $enable_function = function ($query) {
            $query->enable();
        };

        return Role::with(['permissions' => $enable_function, 'menus' => $enable_function])->get();
    }

    /**
     * @expalin GET ROLE LIST
     * @param int $size
     * @return LengthAwarePaginator
     * @method
     * @author 陈文小超
     * @maxim from专注to执行
     * @time 2021/3/31/16:02
     */
    public function paginate(int $size): LengthAwarePaginator
    {
        $enableFunc = function ($query) {
            $query->enable();
        };
        $roles = Role::with(['permissions' => $enableFunc, 'menus' => $enableFunc])->recent()->paginate($size);

        return $roles;
    }

    /**
     * @expalin GET ROLE BY ID
     * @param int $id
     * @return Role
     * @method
     * @author 陈文小超
     * @maxim from专注to执行
     * @time 2021/3/31/15:26
     */
    public function find(int $id): Role
    {
        return Role::findOrFail($id);
    }

    /**
     * @expalin CREATE A ROLE
     * @param RoleStoreRequest $request
     * @return Role
     * @method
     * @author 陈文小超
     * @maxim from专注to执行
     * @time 2021/3/31/14:47
     */
    public function store(RoleStoreRequest $request): Role
    {
        $role = null;

        DB::transaction(function () use (&$role, $request) {
            $menu_ids = (array) $request->input('menus', []);
            $permission_ids = (array) $request->input('permissions', []);
            // 创建角色
            $role = Role::create($request->only(['name', 'is_enable']));

            // 同步权限
            $permissions = Permission::enable()->findMany($permission_ids);
            $role->syncPermissions($permissions);

            // 同步菜单
            $role->menus()->sync(Menu::enable()->whereIn('id', $menu_ids)->pluck('id')->toArray());
        });

        return $role;
    }

    /**
     * @expalin UPDATE ROLE BY ID
     * @param Role $role
     * @param RoleUpdateRequest $request
     * @return Role
     * @method
     * @author 陈文小超
     * @maxim from专注to执行
     * @time 2021/3/31/15:37
     */
    public function update(Role $role, RoleUpdateRequest $request): Role
    {
        DB::transaction(function () use (&$role, $request) {
            $menu_ids = (array) $request->input('menus', []);
            $permission_ids = (array) $request->input('permissions', []);

            // 编辑角色
            $role->name = $request->input('name');
            $role->is_enable = $request->input('is_enable') ? Role::ENABLE_TRUE : Role::ENABLE_FALSE;
            $role->save();

            // 同步权限
            $permissions = Permission::enable()->findMany($permission_ids);
            $role->syncPermissions($permissions);

            // 同步菜单
            $role->menus()->sync(Menu::enable()->whereIn('id', $menu_ids)->pluck('id')->toArray());
        });

        return $role;
    }

    /**
     * @expalin DELETE ROLE BY ID
     * @param Role $role
     * @return bool
     * @method
     * @author 陈文小超
     * @maxim from专注to执行
     * @time 2021/3/31/16:00
     */
    public function destroy(Role $role): bool
    {
        // 计算子角色数量
        $userCount = $role->users()->count();
        if ($userCount) {
            return false;
        }

        DB::transaction(function () use ($role) {
            // 删除关联菜单
            $role->menus()->detach();

            // 删除关联权限
            $role->permissions()->detach();

            $role->delete();
        });

        return true;
    }
}
